package htdi.act.usrmgr.models;

import act.aaa.model.UserBase;
import act.aaa.model.UserLinked;
import act.crypto.AppCrypto;
import act.db.jpa.JPADao;
import act.event.EventBus;
import act.util.Stateless;
import org.osgl.aaa.Principal;
import org.osgl.util.E;
import org.osgl.util.S;

import java.nio.charset.StandardCharsets;
import javax.inject.Inject;
import javax.persistence.*;

@Entity
public class User extends UserBase implements UserLinked {

    public static final String EVENT_SIGN_UP = "sign-up";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    public String firstName;
    public String lastName;

    public String getFullName() {
        return isASCII() ? S.concat(firstName, " ", lastName) : S.concat(lastName, firstName);
    }

    private boolean isASCII() {
        return String.valueOf(firstName.charAt(0)).getBytes(StandardCharsets.UTF_8).length == 1;
    }

    @Override
    public boolean isLinkedTo(Principal user) {
        return S.eq(email, user.getName());
    }

    @Stateless
    public static class Dao extends JPADao<Long, User> {

        @Inject
        private AppCrypto crypto;

        @Inject
        private EventBus eventBus;

        public User findByUsername(String username) {
            return findOneBy("email", username);
        }

        public boolean authenticate(String username, char[] password) {
            User user = findByUsername(username);
            if (null == user) {
                return false;
            }
            return user.verifyPassword(password);
        }

        public void signUp(User user) {
            verifyNewSignUp(user);
            user.setPassword(S.secureRandom().toCharArray());
            save(user);
            String tk = crypto.generateToken(user.email);
            eventBus.trigger(EVENT_SIGN_UP, user, tk);
        }

        private void verifyNewSignUp(User user) {
            E.illegalStateIf(countBy("email", user.email) > 0, "邮件已经注册过了");
        }

    }
}